package com.listeningframework.boot.autoconfigure.security;

import com.listeningframework.boot.autoconfigure.security.overrides.JWTTokenConfigurer;
import com.listeningframework.boot.autoconfigure.security.overrides.JWTTokenProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

/**
 * @author listening
 * @version $Id: SpringSecurityBeansConfiguration.java, v 0.1 2015年7月13日 下午9:58:23 listening Exp $
 *          SpringSecurity Beans Configuration
 */
@Configuration
@ConditionalOnClass({AuthenticationManager.class, GlobalAuthenticationConfigurerAdapter.class})
@EnableConfigurationProperties(ListeningSecurityProperties.class)
@ConditionalOnProperty(prefix = "listening.security.jwt", name = "enabled", havingValue = "true", matchIfMissing = false)
public class JWTTokenSecurityConfiguration extends WebSecurityConfigurerAdapter {

    /**
     * JWTToken Provider
     *
     * @return JWTTokenProvider
     */
    @Bean
    @ConditionalOnMissingBean(JWTTokenProvider.class)
    public JWTTokenProvider getJWTTokenProvider() {
        return new JWTTokenProvider();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.csrf()
                .disable()
                .headers()
                .frameOptions()
                .disable()
                .and()
                .exceptionHandling()
//            .authenticationEntryPoint(getEntryPoint())
//            .accessDeniedHandler(new ListeningAccessDeniedHandler("/403"))
                .and().logout()
                .deleteCookies("JSESSIONID", "SESSION")
                .and().rememberMe()
                .and().csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/api/authenticate").permitAll()
                .antMatchers("/management/**").hasAuthority("ROLE_ADMIN")
                .antMatchers("/swagger-resources/configuration/ui").permitAll()
                .regexMatchers("/listeningoauth/.*|/oauth/.*").permitAll()
                .regexMatchers("/listeningboot/.*|/logout").permitAll()
                .anyRequest().authenticated()
                .and()
                .apply(new JWTTokenConfigurer(getJWTTokenProvider()));
        // @formatter:on
    }

}
